package 线程2;
//线程等待.
//线程和线程之间,调度顺序是完全不确定(取决于操作系统调度器自身的实现)

//但是有的时候,希望这里的顺序是可控的~~
//此时线程等待,就是一种办法
//这里的线程等待,主要就是控制线程结束的先后顺序.

//一种常见的逻辑:t1线程,创建t2,t3,t4,让这三个新的线程来分别执行一些任务.
//然后t1线程最后在这里汇总结果
//这样的场景就需要t1的结束时机必须比t2,t3,t4都迟

//Thread t = new Thread();
//t.join() //执行到这个代码,调用这个代码的线程就会阻塞等待(具体来说就是,操作系统短时间内不会把这个线程调度到CPU上了)

import java.util.TreeMap;

/**
 * 以前也见过阻塞等待的代码..
 * Scanner scanner = new Scanner(System.in);
 * sanner.nextInt();//尝试从键盘中读入一个数据
 */
public class TestDemo4 {
    public static void main(String[] args) {
        //创建 t1
        Thread t1 = new Thread(){
            @Override
            public void run() {
                int count = 0;
                while(count < 5){
                    count++;
                    System.out.println("线程执行中...");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("线程执行结束");
            }
        };
        t1.start();//触发了新的执行流,创建一个新的线程,由新的线程来执行上面的操作

        //执行start方法的时候,就会立刻创建出一个新的线程来,
//        同时main这个线程也立刻会往下执行,就执行到t1.join
        //执行到t1.join()的时候,就会发现t1线程还是在运行中
        //只要t1在运行中,join方法就会一直阻塞等待.一直等到t1线程执行结束(run执行完了)

        //主线程
        try {
            Thread.sleep(7000);
//            如果改成这样呢,join会直接结束.因为当前t1线程已经完成,join就直接完成了
            //此处的join会阻塞等待
            System.out.println("join执行开始");
            t1.join();
            System.out.println("join执行结束");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
//        public void join() 等待线程结束
//        public void join(long millis) 等待线程结束，最多等 millis 毫秒
//        public void join(long millis, int nanos) 同理，但可以更高精度
        //join死等是一件很危险的事
    }
}
